package com.cloudspace.yunloan.player.base;

import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.util.Log;
import android.view.SurfaceHolder;

import com.cloudspace.yunloan.player.Constants;

import java.io.IOException;

public class MediaPlayerSystem extends AbsMediaPlayer {

    private MediaPlayer mMediaPlayer;
    private int mCurrentBufferPercentage;

    public MediaPlayerSystem(Context context) {
        Log.d(Constants.MEDIAPLAYER_LOG_TAG, "System player: init.");
        mMediaPlayer = new MediaPlayer();
        mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

            @Override
            public void onPrepared(MediaPlayer mp) {
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "System player: onPrepared");
                mPlayState = STATE_PREPARED;
                if (null != mOnPreparedListener) {
                    mOnPreparedListener.onPrepared(mp);
                }
            }
        });
        mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {

            @Override
            public void onCompletion(MediaPlayer mp) {
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "System player: onComplete");
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "mOnCompletionListener == null:" + (mOnCompletionListener == null));
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "null != mOnPlayStateChangeListener:" + (null != mOnPlayStateChangeListener));
                if (null != mOnCompletionListener) {
                    mOnCompletionListener.onCompletion(mp);
                }
                if (null != mOnPlayStateChangeListener) {
                    mOnPlayStateChangeListener.onPlayStateChange(STATE_PLAYBACK_COMPLETED);
                }
            }

        });
        mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {

            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                Log.e(Constants.MEDIAPLAYER_LOG_TAG, "System player: onError, what="
                        + what + ", extra=" + extra);
                mPlayState = STATE_ERROR;
                if (null != mOnPlayStateChangeListener) {
                    mOnPlayStateChangeListener.onPlayStateChange(STATE_ERROR);
                }

                if (null != mOnErrorListener) {
                    return mOnErrorListener.onError(mp, what, extra);
                }
                return false;
            }

        });
        mMediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {

            @Override
            public void onBufferingUpdate(MediaPlayer mp, int percent) {
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "System player: onBufferingUpdate, percent=" + percent);
                mCurrentBufferPercentage = percent;
                if (null != mOnBufferingUpdateListener) {
                    mOnBufferingUpdateListener.onBufferingUpdate(mp, percent);
                }
            }
        });
        mMediaPlayer.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {

            @Override
            public void onSeekComplete(MediaPlayer mp) {
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "System player: onSeekComplete");
                if (null != mOnPlayStateChangeListener) {
                    if (stateBeforeSeek == STATE_PLAYING || stateBeforeSeek == STATE_PAUSED) {
                        mOnPlayStateChangeListener.onPlayStateChange(stateBeforeSeek);
                    }
                }
            }
        });
        mMediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {

            @Override
            public void onVideoSizeChanged(MediaPlayer mp, int arg1, int arg2) {
                Log.d(Constants.MEDIAPLAYER_LOG_TAG, "System player: onVideoSizeChanged, arg1="
                        + arg1 + ", arg2=" + arg2);
                if (null != mVideoSizeChangedListener) {
                    mVideoSizeChangedListener.onVideoSizeChanged(mp, arg1, arg2);
                }
            }
        });
    }

    @Override
    public void setDataSource(String path) {
        if (mPlayState != STATE_IDLE) {
            return;
        }
        mPlayState = STATE_PREPARING;
        try {
            mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            Log.e(Constants.MEDIAPLAYER_LOG_TAG, "System player: The final processed address to play, path=" + path);
            mMediaPlayer.setDataSource(path);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            Log.e(Constants.MEDIAPLAYER_LOG_TAG, "System player: IllegalArgumentException in setDataSource.");
        } catch (SecurityException e) {
            e.printStackTrace();
            Log.e(Constants.MEDIAPLAYER_LOG_TAG, "System player: SecurityException in setDataSource.");
        } catch (IllegalStateException e) {
            e.printStackTrace();
            Log.e(Constants.MEDIAPLAYER_LOG_TAG, "System player: IllegalStateException in setDataSource.");
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(Constants.MEDIAPLAYER_LOG_TAG, "System player: IOException in setDataSource.");
        }
    }

    @Override
    public void start() {
        if (mPlayState == STATE_ERROR || mPlayState == STATE_IDLE) {
            return;
        }
        mPlayState = STATE_PLAYING;
        mMediaPlayer.start();
        if (null != mOnPlayStateChangeListener) {
            mOnPlayStateChangeListener.onPlayStateChange(STATE_PLAYING);
        }
    }

    @Override
    public void pause() {
        if (mPlayState == STATE_ERROR || mPlayState == STATE_IDLE) {
            return;
        }
        mMediaPlayer.pause();
        mPlayState = STATE_PAUSED;
        if (null != mOnPlayStateChangeListener) {
            mOnPlayStateChangeListener.onPlayStateChange(STATE_PAUSED);
        }
    }

    @Override
    public void prepare() {
        mPlayState = STATE_PREPARING;
        try {
            mMediaPlayer.prepare();
            if (null != mOnPlayStateChangeListener) {
                mOnPlayStateChangeListener.onPlayStateChange(STATE_PREPARING);
            }
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void prepareAsync() {
        if (mPlayState != STATE_PREPARING) {
            return;
        }
        mMediaPlayer.prepareAsync();
        if (null != mOnPlayStateChangeListener) {
            mOnPlayStateChangeListener.onPlayStateChange(STATE_PREPARING);
        }
    }

    @Override
    public void stop() {
        if (mPlayState == STATE_IDLE || mPlayState == STATE_ERROR) {
            return;
        }
        mMediaPlayer.stop();
        mPlayState = STATE_IDLE;
        if (null != mOnPlayStateChangeListener) {
            mOnPlayStateChangeListener.onPlayStateChange(STATE_IDLE);
        }
    }

    @Override
    public void release() {
        mPlayState = STATE_IDLE;
        mMediaPlayer.release();
    }

    @Override
    public void reset() {
        mMediaPlayer.reset();
        mPlayState = STATE_IDLE;
        if (null != mOnPlayStateChangeListener) {
            mOnPlayStateChangeListener.onPlayStateChange(STATE_IDLE);
        }
    }

    int stateBeforeSeek = STATE_PLAYING;

    @Override
    public void seekTo(int msec) {
        if (mPlayState != STATE_PLAYING && mPlayState != STATE_PAUSED && mPlayState != STATE_SEEKING && mPlayState != STATE_PREPARED) {
            return;
        }
        if (mPlayState == STATE_PLAYING || mPlayState == STATE_PAUSED) {
            stateBeforeSeek = mPlayState;
        }
        mPlayState = STATE_SEEKING;
        mMediaPlayer.seekTo(msec);
        if (null != mOnPlayStateChangeListener) {
            mOnPlayStateChangeListener.onPlayStateChange(STATE_SEEKING);
        }
    }

    @Override
    public int getCurrentPosition() {
        if (mPlayState != STATE_PLAYING && mPlayState != STATE_PAUSED && mPlayState != STATE_SEEKING && mPlayState != STATE_PREPARED) {
            return 0;
        }
        return mMediaPlayer.getCurrentPosition();
    }

    @Override
    public int getDuration() {
        if (mPlayState != STATE_PLAYING && mPlayState != STATE_PAUSED && mPlayState != STATE_SEEKING && mPlayState != STATE_PREPARED) {
            return 0;
        }
        return mMediaPlayer.getDuration();
    }

    @Override
    public int getPlayerBufferedProgress() {
        return mCurrentBufferPercentage;
    }

    @Override
    public void setDisplay(SurfaceHolder sh) {
        try {
            mMediaPlayer.setDisplay(sh);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean isPlaying() {
        if (mPlayState == STATE_IDLE || mPlayState == STATE_ERROR) {
            return false;
        }
        return mMediaPlayer.isPlaying();
    }

}
